﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace TaskFramework.Tests
{
    [TestFixture]
    public class TaskTrackerFixture
    {
        [Test]
        public void should_add_tasks_to_the_tracker_and_infer_root_task_ids()
        {
            ITaskTracker tracker = new TaskTracker();

            tracker.AddTask(1);
            tracker.AddTask(2, 1);
            tracker.AddTask(3, 2);

            Assert.AreEqual(1, tracker.ResolveRootTaskId(1));
            Assert.AreEqual(1, tracker.ResolveRootTaskId(2));
            Assert.AreEqual(1, tracker.ResolveRootTaskId(3));
        }

        [Test]
        public void should_not_remove_the_task_from_tracker_while_other_references_exist()
        {
            ITaskTracker tracker = new TaskTracker();

            tracker.AddTask(1);
            tracker.AddTask(2, 1);
            tracker.AddTask(3, 2);

            tracker.RemoveTask(1);
            Assert.AreEqual(1, tracker.ResolveRootTaskId(1));
            Assert.AreEqual(1, tracker.ResolveRootTaskId(2));
            Assert.AreEqual(1, tracker.ResolveRootTaskId(3));
        }

        [Test, ExpectedException(typeof(TaskNotTrackedException))]
        public void should_remove_all_task_references_and_ensure_that_tracker_data_is_removed()
        {
            ITaskTracker tracker = new TaskTracker();

            tracker.AddTask(1);
            tracker.AddTask(2, 1);
            tracker.AddTask(3, 2);

            tracker.RemoveTask(1);
            tracker.RemoveTask(2);
            tracker.RemoveTask(3);

            Assert.AreEqual(1, tracker.ResolveRootTaskId(1));
        }

        [Test]
        public void should_verify_that_a_task_is_currently_being_tracked()
        {
            ITaskTracker tracker = new TaskTracker();

            tracker.AddTask(1);
            tracker.AddTask(2, 1);
            tracker.AddTask(3, 2);

            Assert.IsTrue(tracker.IsTracked(1));
            Assert.IsTrue(tracker.IsTracked(2));
            Assert.IsTrue(tracker.IsTracked(3));
            Assert.IsFalse(tracker.IsTracked(4));

            // tasks are tracked until all references to their root task are removed
            // remove all 3 tasks and check again
            tracker.RemoveTask(1);
            tracker.RemoveTask(2);
            tracker.RemoveTask(3);

            Assert.IsFalse(tracker.IsTracked(1));
            Assert.IsFalse(tracker.IsTracked(2));
            Assert.IsFalse(tracker.IsTracked(3));
            Assert.IsFalse(tracker.IsTracked(4));

            bool allReferencesRemoved = false;

            try
            {
                tracker.ResolveRootTaskId(3);
            }
            catch (TaskNotTrackedException)
            {
                allReferencesRemoved = true;
            }

            Assert.IsTrue(allReferencesRemoved);
        }
    }
}